
package com.insigma.business.qrcode.common._consumer.impl;

import com.google.common.base.Strings;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.insigma.business.common.dto.CurrentUser;
import com.insigma.business.common.utils.CurrentUserUtil;
import com.insigma.business.qrcode.common.dto.CommonAdminAreaDTO;
import com.insigma.business.qrcode.common.dto.CommonAdminAreaSearchRequest;
import com.insigma.business.qrcode.common._consumer.CommonAdminAreaConsumer;
import com.insigma.business.qrcode.common._provider.CommonAdminAreaProvider;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.util.AdminAreaCodeUtils;
import com.insigma.business.qrcode.common.vo.BaseResponse;
import com.insigma.business.qrcode.soldier.request.BaseGetRequest;
import com.insigma.business.qrcode.soldier._provider.SoldierBasicInfoProvider;
import com.insigma.business.qrcode.soldier.util.BizCheckUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Service("commonAdminAreaConsumer")
public class CommonAdminAreaConsumerImpl implements CommonAdminAreaConsumer {

    private Cache<String, Map<String, CommonAdminAreaDTO>> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(24, TimeUnit.HOURS).build();

    private String allKey = "ALL_AREA";

    @Resource
    private CommonAdminAreaProvider commonAdminAreaProvider;

    @Resource
    private SoldierBasicInfoProvider soldierBasicInfoProvider;

    @Override
    public void testCleanSetSoldier() {
        soldierBasicInfoProvider.testRefreshBaicInfoToDB();
    }

    @Override
    public BaseResponse<List<CommonAdminAreaDTO>> findSubAreaList(String adminAreaCode) {
        if (StringUtils.isBlank(adminAreaCode)) {
            CommonAdminAreaDTO dto = new CommonAdminAreaDTO();
            dto.setValue("浙江省");
            dto.setId("33");
            dto.setLevel(1);
            return  new BaseResponse<List<CommonAdminAreaDTO>>(true, Lists.newArrayList(dto));
        }

        String shortCode = AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode);
        int nextLevel = AdminAreaCodeUtils.getLevel(adminAreaCode) + 1;

        List<CommonAdminAreaDTO> list = Lists.newArrayList();
        Map<String, CommonAdminAreaDTO> allArea = getAllAreaCode();
        for (Map.Entry<String, CommonAdminAreaDTO> entry : allArea.entrySet()) {
            CommonAdminAreaDTO value = entry.getValue();
            if (AdminAreaCodeUtils.getLevel(value.getId()) == nextLevel && value.getId().startsWith(shortCode)) {
                list.add(value);
            }
        }

        return new BaseResponse<List<CommonAdminAreaDTO>>(true, list);
    }

    @Override
    public BaseResponse<CommonAdminAreaDTO> getCommonAdminArea(final BaseGetRequest baseGetRequest) {
        Map<String, CommonAdminAreaDTO> allArea = getAllAreaCode();

        return  new BaseResponse<CommonAdminAreaDTO>(true, allArea.get(baseGetRequest.getId()));
    }



    @Override
    public String checkIsChildAdminAreaCode(String adminAreaCode) {
        CommonAdminAreaDTO adminAreaOfEmployee = findAdminAreaOfEmployee();
        if (Strings.isNullOrEmpty(adminAreaCode)) {
            return adminAreaOfEmployee.getId();
        }
        BizCheckUtil.checkIsTrue(AdminAreaCodeUtils.checkIsFatherArea(adminAreaOfEmployee.getId(), adminAreaCode), "访问非法");
        return adminAreaCode;
    }
    @Override
    public CommonAdminAreaDTO findAdminAreaOfEmployee() {
        CurrentUser sessionGovEmployee = CurrentUserUtil.getCurrentUser();
        BizCheckUtil.checkNotNull(sessionGovEmployee, "用户非法");
        BaseResponse<CommonAdminAreaDTO> area = commonAdminAreaProvider.findAdminAreaOfEmployee(sessionGovEmployee.getSoldierId());
        if (area == null || area.getDto() == null) {
            return null;
        }
        return area.getDto();
    }

    @Override
    public CommonAdminAreaDTO findAdminAreaOfEmployee(String userId) {
        BaseResponse<CommonAdminAreaDTO> area = commonAdminAreaProvider.findAdminAreaOfEmployee(userId);
        if (area == null || area.getDto() == null) {
            return null;
        }
        return area.getDto();
    }

    @Override
    public CommonAdminAreaDTO getAdminAreaById(String areaCode) {
        Map<String, CommonAdminAreaDTO> allArea = getAllAreaCode();

        return allArea.get(areaCode);
    }

    @Override
    public BaseResponse<List<CommonAdminAreaDTO>> findQGSubAreaList(String adminCode) {
        return commonAdminAreaProvider.findQGSubAreaList(adminCode);
    }

    @Override
    public BaseResponse<String> analyseAreaCodeByBasicInfoForOther(String address) {
        return commonAdminAreaProvider.analyseAreaCodeByBasicInfoForOther(address);
    }

    @Override
    public String getQXName(String adminAreaCode) {
        Map<String, CommonAdminAreaDTO> allArea = getAllAreaCode();
        CommonAdminAreaDTO commonAdminAreaDTO = allArea.get(AdminAreaCodeUtils.fillAreaCode(AdminAreaCodeUtils.getCutAdminAreaCode(adminAreaCode, 3)));
        if (commonAdminAreaDTO == null) {
            return null;
        }
        return commonAdminAreaDTO.getValue();
    }

    private Map<String, CommonAdminAreaDTO> getAllAreaCode() {
        Map<String, CommonAdminAreaDTO> allArea = cache.getIfPresent(allKey);
        if (allArea == null) {
            setAllArea();
            allArea = cache.getIfPresent(allKey);
        }
        return allArea;
    }

    private void setAllArea() {
        CommonAdminAreaSearchRequest searchRequest = new CommonAdminAreaSearchRequest(1, Integer.MAX_VALUE);
        BasePagingResponse<List<CommonAdminAreaDTO>> listBasePagingResponse = commonAdminAreaProvider.searchCommonAdminArea(searchRequest);
        List<CommonAdminAreaDTO> dto = listBasePagingResponse.getDto();
        Map<String, CommonAdminAreaDTO> map = Maps.newLinkedHashMap();
        for (CommonAdminAreaDTO commonAdminAreaDTO : dto) {
            map.put(commonAdminAreaDTO.getId(), commonAdminAreaDTO);
        }

        cache.put(allKey, map);
    }


}
